package com.itwlj.service.impl;

import com.itwlj.constant.MessageConstant;
import com.itwlj.constant.StatusConstant;
import com.itwlj.context.BaseContext;
import com.itwlj.dto.OrderDTO;
import com.itwlj.entity.User;
import com.itwlj.exception.DuplicatePaymentException;
import com.itwlj.exception.InsufficientBalanceException;
import com.itwlj.exception.OrderTimeoutException;
import com.itwlj.exception.PasswordErrorException;
import com.itwlj.service.OrderService;
import com.itwlj.service.PayService;
import com.itwlj.service.UserService;
import com.itwlj.vo.OrderVO;
import com.itwlj.vo.PayVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;

@Service
public class PayServiceImpl implements PayService {

    @Autowired
    private OrderService orderService;
    @Autowired
    private UserService userService;

    @Value("${mall.countdown}")
    private Integer countdown;

    /**
     * 支付预览
     *
     * @param id
     * @return
     */
    public PayVO getPayPreview(Long id) {
        OrderVO orderVO = orderService.getById(id);

        User user = userService.getById(BaseContext.getCurrentId());
        return PayVO.builder()
                .id(orderVO.getId())
                .balance(user.getBalance())
                .countdown(countdown / 1000 / 60)
                .payChannel(orderVO.getPayChannel())
                .payMoney(orderVO.getTotalMoney())
                .payResult(orderVO.getPayResult())
                .build();
    }

    /**
     * 支付订单
     *
     * @param id
     * @param password
     */
    @Transactional
    public void payOrder(Long id, String password) {
        OrderVO orderVO = orderService.getById(id);
        User user = userService.getById(orderVO.getUserId());
        BigDecimal balance = user.getBalance().subtract(orderVO.getTotalMoney());

        //验证密码
        if (!user.getPassword().equals(DigestUtils.md5DigestAsHex(password.getBytes()))) {
            throw new PasswordErrorException(MessageConstant.PASSWORD_ERROR);
        }

        //检查订单是否已取消
        if (orderVO.getOrderState() == 4) {
            throw new OrderTimeoutException(MessageConstant.ORDER_TIMEOUT);
        }

        // 检查余额是否足够
        if (balance.compareTo(BigDecimal.ZERO) < 0) {
            throw new InsufficientBalanceException(MessageConstant.INSUFFICIENT_BALANCE);
        }

        //检查订单是否已有支付结果
        if (orderVO.getPayResult() != null) {
            throw new DuplicatePaymentException(MessageConstant.DUPLICATE_PAYMENT);
        }

        //扣减余额
        userService.deductBalance(user.getId(), balance);

        OrderDTO orderDTO = new OrderDTO();
        orderDTO.setId(id);
        orderDTO.setOrderState(StatusConstant.ORDER_PAID);
        orderDTO.setPayTime(LocalDateTime.now());
        orderDTO.setPayResult(StatusConstant.ORDER_PAYMENT_SUCCESS);
        orderService.update(orderDTO);
    }
}
